package com.glo.quiki.req;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.glo.quiki.model.LoginResult;
import com.glo.quiki.model.QuikiPaymentOrder;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.ReadContext;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.json.JSONException;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.zip.GZIPInputStream;

@Slf4j
public class QuikiRequest {

    private static final Map<String, String> headerCommon = new HashMap<>();
    private static final String LOGIN_URL = "https://dev.quikipay.com/login";
    private static final String GET_CVU_INFO_URL = "https://dev.quikipay.com/assets/cvu/info/";
    private static final String CREATE_BENEFICIARY_URL = "https://dev.quikipay.com/assets/create/beneficiary/ ";
    private static final String CREATE_TRANSFER_URL = "https://dev.quikipay.com/assets/fee/text/cvu/%s/%s/%s";

    private static final OkHttpClient okHttpClient = getCookieClient();

    static {
        headerCommon.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7");
        headerCommon.put("Accept-Encoding", "gzip, deflate, br, zstd");
        headerCommon.put("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8");
        headerCommon.put("Connection", "keep-alive");
        headerCommon.put("Host", "dev.quikipay.com");
        headerCommon.put("Sec-CH-UA", "\"Chromium\";v=\"134\", \"Not:A-Brand\";v=\"24\", \"Microsoft Edge\";v=\"134\"");
        headerCommon.put("Sec-CH-UA-Mobile", "?0");
        headerCommon.put("Sec-CH-UA-Platform", "\"Windows\"");
        headerCommon.put("Sec-Fetch-Dest", "document");
        headerCommon.put("Sec-Fetch-Mode", "navigate");
        headerCommon.put("sec-fetch-site", "same-origin");
        headerCommon.put("Sec-Fetch-User", "?1");
        headerCommon.put("Upgrade-Insecure-Requests", "1");
        headerCommon.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0");
    }

    public static OkHttpClient getCookieClient() {
        QuikiSimpleCookieJar cookieJar = new QuikiSimpleCookieJar();

        OkHttpClient client = new OkHttpClient.Builder()
                .cookieJar(cookieJar)
                .followRedirects(true)
                .build();
        return client;
    }

    /**
     * 1:加载登录首页
     */
    public static String loadingLoginPage()  {
        Request request = new Request.Builder().url(LOGIN_URL).get().headers(Headers.of(headerCommon)).build();

        try (Response response = okHttpClient.newCall(request).execute()) {
            log.info("加载登录页面,返回状态码: {}", response.code());
            if (response.body() != null) {
                if ("gzip".equalsIgnoreCase(response.header("Content-Encoding"))) {
                    try (GZIPInputStream gis = new GZIPInputStream(response.body().byteStream());
                         InputStreamReader reader = new InputStreamReader(gis);
                         BufferedReader bufferedReader = new BufferedReader(reader)) {

                        StringBuilder decompressedResponse = new StringBuilder();
                        String line;
                        while ((line = bufferedReader.readLine()) != null) {
                            decompressedResponse.append(line).append("\n");
                        }
                        return getCsrfToken(decompressedResponse.toString());
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("加载登录页面时发生未知错误", e);
        }
        return null;
    }

    /**
     * 2:提交登录请求
     */
    public static LoginResult submitLoginRequest(Map<String, String> accountInfo) {
        //将 Map 转换为 FormBody
        FormBody.Builder formBuilder = new FormBody.Builder();
        for (Map.Entry<String, String> entry : accountInfo.entrySet()) {
            formBuilder.add(entry.getKey(), entry.getValue());
        }

        Request request = new Request.Builder()
                .url(LOGIN_URL)
                .post(formBuilder.build())
                .headers(Headers.of(headerCommon))
                .header("origin", "https://dev.quikipay.com")
                .header("referer", "https://dev.quikipay.com/login")
                .build();

        try (Response response = okHttpClient.newCall(request).execute()) {
            log.info("提交登录: " + response.code());
            String rememberToken = ((QuikiSimpleCookieJar)okHttpClient.cookieJar()).getRememberToken();
            LoginResult loginResult = new LoginResult();
            if (rememberToken != null) {

                // 按 `=` 进行分割，只分割 **前两部分**
                String[] parts = rememberToken.split("=", 2);
                // `=` 之前的部分
                String key = parts[0];
                // `=` 之后的部分
                String value = parts.length > 1 ? parts[1] : "";
                log.info("登录成功：{}={}", key, value);
//                loginResult.set
                loginResult.setRememberCookie(value);
            }
            if (response.body() != null && response.code() == 200) {
                // 检查是否是 gzip 压缩
                // 处理 GZIP 压缩响应
                if ("gzip".equalsIgnoreCase(response.header("Content-Encoding"))) {
                    String csrfToken = getCsrfToken(decompressGzipResponse(response.body()));
                    loginResult.setToken(csrfToken);
                    return loginResult;
                } else {
                    String csrfToken = getCsrfToken(response.body().string());
                    loginResult.setToken(csrfToken);
                    return loginResult;
                }
            }
        } catch (IOException e) {
            log.error(e.getMessage());
        }
        return null;
    }

    /**
     * 解压 GZIP 响应并提取 CSRF Token
     *
     * @param body 响应体
     * @return CSRF Token 字符串
     * @throws IOException 如果解压失败
     */
    private static String decompressGzipResponse(ResponseBody body) throws IOException {
        try (GZIPInputStream gis = new GZIPInputStream(body.byteStream());
             InputStreamReader reader = new InputStreamReader(gis);
             BufferedReader bufferedReader = new BufferedReader(reader)) {

            StringBuilder decompressedResponse = new StringBuilder();
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                decompressedResponse.append(line).append("\n");
            }
            return decompressedResponse.toString();
        }
    }

    /**
     * 获取token
     *
     * @param html 返回的html页面
     * @return token
     */
    private static String getCsrfToken(String html) {
        int start = html.indexOf("csrf-token\" content=\"") + 21;
        int end = html.indexOf("\"", start);
        return (start > 20 && end > start) ? html.substring(start, end) : null;
    }

    /**
     * 查询代收订单账单
     *
     * @param loginResult
     * @param queryStartDate
     * @param queryEndDate
     * @return
     * @throws Exception
     */
    public static List<QuikiPaymentOrder>  sendSelectPaymentOrder(LoginResult loginResult, LocalDate queryStartDate, LocalDate queryEndDate) throws Exception {
        String dateStr = "%s - %s";
        dateStr = String.format(dateStr, queryStartDate, queryEndDate);
        dateStr = URLEncoder.encode(dateStr, "UTF-8").replace("+", "%20");

        String url = "https://dev.quikipay.com/assets/cvu/transactions?page=&_token=%s&cvu_id=726&gw_trxId=All&range=";
        url = String.format(url, loginResult.getToken()) + dateStr;

        Map<String, String> headMap = new HashMap<>();
        headMap.put("Accept", "*/*");
        headMap.put("Accept-Encoding", "gzip, deflate, br, zstd");
        headMap.put("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8");
        headMap.put("Connection", "keep-alive");
        headMap.put("Referer", "https://dev.quikipay.com/assets/cvu/transactions");
        headMap.put("Sec-Fetch-Dest", "empty");
        headMap.put("Sec-Fetch-Mode", "cors");
        headMap.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36");
        headMap.put("X-Requested-With", "XMLHttpRequest");
        headMap.put("sec-ch-ua", "\"Chromium\";v=\"134\", \"Not:A-Brand\";v=\"24\", \"Google Chrome\";v=\"134\"");
        headMap.put("sec-ch-ua-mobile", "?0");
        headMap.put("sec-ch-ua-platform", "\"macOS\"");
        if (loginResult.getRememberCookie() != null){
            headMap.put("Cookie", "remember_web_" + loginResult.getRememberCookie());
        }

        Request request = new Request.Builder()
                .url(url)
                .get()
                .headers(Headers.of(headMap))
                .build();

        try (Response response = okHttpClient.newCall(request).execute()) {
            if (response.isSuccessful()) {
                // 从 Response 获取新返回的 Cookie
                List<String> responseCookies = response.headers("Set-Cookie");
                log.info("Response Set-Cookie Headers:");
                for (String cookieHeader : responseCookies) {
                    log.info(cookieHeader);
                }
                if (response.body() != null) {
                    if ("gzip".equalsIgnoreCase(response.header("Content-Encoding"))) {
                        try (GZIPInputStream gis = new GZIPInputStream(response.body().byteStream());
                             InputStreamReader reader = new InputStreamReader(gis);
                             BufferedReader bufferedReader = new BufferedReader(reader)) {

                            StringBuilder decompressedResponse = new StringBuilder();
                            String line;
                            while ((line = bufferedReader.readLine()) != null) {
                                decompressedResponse.append(line).append("\n");
                            }
                            String html = decompressedResponse.toString();

                            List<QuikiPaymentOrder> quikiPaymentOrders = QuikiParseHtml.parseTransactions(html);
//                            log.info(html);
                            return quikiPaymentOrders;
                        }
                    }
                    // 检查是否是 gzip 压缩
                    // 处理 GZIP 压缩响应
                    if ("gzip".equalsIgnoreCase(response.header("Content-Encoding"))) {
                        String html = decompressGzipResponse(response.body());
                        List<QuikiPaymentOrder> quikiPaymentOrders = QuikiParseHtml.parseTransactions(html);
//                            log.info(html);
                        return quikiPaymentOrders;
                    }
                }
            }
        }
        return null;
    }

    /**
     * 创建转账订单
     *
     * @param loginResult
     * @return
     * @throws Exception
     */
    public static  void sendCreateTransferOrder(LoginResult loginResult, String cvuAccount, String orderAmount) throws Exception {

        String url = GET_CVU_INFO_URL+cvuAccount;
        Map<String, String> headMap = new HashMap<>();
        headMap.put("X-Requested-With", "XMLHttpRequest");
//        if (loginResult.getRememberCookie() != null){
//            headMap.put("Cookie", loginResult.getRememberCookie());
//        }
        Request request = new Request.Builder()
                .url(url)
                .get()
                .headers(Headers.of(headMap))
                .build();

        try (Response response = okHttpClient.newCall(request).execute()) {
            if (response.body() != null && response.body().contentType().toString().contains("application/json")) {
//                String rememberToken = ((QuikiSimpleCookieJar)okHttpClient.cookieJar()).getRememberToken();
//                if (rememberToken != null) {
//
//                    // 按 `=` 进行分割，只分割 **前两部分**
//                    String[] parts = rememberToken.split("=", 2);
//                    // `=` 之前的部分
//                    String key = parts[0];
//                    // `=` 之后的部分
//                    String value = parts.length > 1 ? parts[1] : "";
//                    log.info("登录成功：{}={}", key, value);
//                }
                String html = response.body().string();
                log.info("getCvuInfo：{}",html);

//                ObjectMapper objectMapper = new ObjectMapper();
//                JsonNode resNode = objectMapper.readTree(html);
//                String data = resNode.get("data").asText();

//                String beneficiaryId = createBeneficiaryRequest(token,data,"accountName");
                //remember_web_59ba36addc2b2f9401580f014c7f58ea4e30989d=eyJpdiI6ImRJRHEvN3h5U1BIZjRiTVVhNUdRbXc9PSIsInZhbHVlIjoianRER0dsZll6VDhETGEyc3c0NWZxYW1TMURNdStBaktkNm5zdHk2Und3Y2E0T0daejZwR1pkclVNUXNtZXdVWFlIcUdQWkZ3RVhwWWFMeWdJZkNuMDVQZ2VJVXRIcVdZUUNuenRucGk0OXE1Umpna215ZWx5WUxMbW9sazc3cGFIVmdwSjBQc3pUdyttYnpnM1F6cUk1aHA3NlpVNG1IQUJqUUFRVXFqMCs2S2RZSTNvblIzTzNPZS9nUFpOWjZMUDZHelBvcGhkSkZocFBVeUNrU290WEtzRXVGeEhSLy9MMDVFZ0FVVFNScz0iLCJtYWMiOiI1YWEyZDQxYTViNTM4NDhlZDhhZDQ5Y2JhOTgwNTE3OTcyN2MxMzIyMzcyNWMzZDRjMDExODc1Zjc4OTkwNDk5IiwidGFnIjoiIn0%3D; XSRF-TOKEN=eyJpdiI6Im9vTlQvaFcxSjVDa1NEenNWOE5VSHc9PSIsInZhbHVlIjoiMnc3TFAvMWxQZ1B1NXRQMTdNbkROWkJGeUNHNjNPWDk3dXA2VVJmc3dtbXg0NllGVm54clVJclBuNnVkYm1NemVoei9PNzZ2N1lmSVBVSFVqWDRDcG9rTjRzVG1OcEltc1VlWjM3L05vclU2ZVl5YllyMEdzSjVNMEp6Ly9hcjYiLCJtYWMiOiJjYjNlNTIwYWE1ODc5MzhjOGM4ZTQ2YjJmOTRmN2I5ZjVhYzM5MGZlYjE0N2EyM2E2YWRiNGIxYWIyY2NjNzk1IiwidGFnIjoiIn0%3D; quikipay_session=eyJpdiI6IkQwbnh1SXIvWnRjdzREZUl1a3F5Z3c9PSIsInZhbHVlIjoiUWFwd1h2NG5tUHF0SlptN0l5RUg4amFyZUhicDdBd3MveUVtelRKYWRVRC91K3VoOStZR093VlgyNndNUmQrUVlLdVNJdkV1eWhzaU1vdkNIZXlFRHRrMXlYVDdGVXF2QWpFVHF3a2txdGduSmNHVmp4UEwxekU2U01Fb1A2UkIiLCJtYWMiOiI0MGQ3NTMwZWEyZmFjMDczNmZiYTBiNjQ1MDQ4ODQ4MmJkM2Y0OTAyMGM3NjAyMDdkNTNlMzI3M2E4ZTRjNTM0IiwidGFnIjoiIn0%3D
                //224685 224683
                String transferRequest = createTransferRequest(orderAmount, "224685", "433967");
                sendVerifyCodeRequest();
                Scanner scanner = new Scanner(System.in);
                String verifyCode = scanner.nextLine();
                sendTransferRequest(loginResult.getToken(),"224683","st123456",orderAmount,verifyCode,"0");
                sendTransferRequest(loginResult.getToken(),"224683","st123456",orderAmount,"","1");

            }
        }
    }

    /**
     * 创建受益人
     * @param token
     * @param cvuInfo
     * @param name
     * @return
     * @throws IOException
     */
    public static String createBeneficiaryRequest(String token,String cvuInfo,String name) throws IOException, JSONException {
        FormBody formBody = new FormBody.Builder()
                .add("_token", token)
                .add("cvu_info", cvuInfo)
                .add("name_this", name)
                .build();
        Request request = new Request.Builder()
                .url(CREATE_BENEFICIARY_URL+URLEncoder.encode(cvuInfo))
                .post(formBody)
                .build();
        Response response = okHttpClient.newCall(request).execute();
        String string = response.body().string();
        log.info("创建受益人返回：{}", string);

        response.close();
        // 使用 JsonPath 查找符合条件的元素
        ReadContext ctx = JsonPath.parse(string);
        net.minidev.json.JSONArray targetNode = ctx.read("$.assets[?(@.alias == '"+name+"')]");

        // 找到符合条件的元素
        targetNode.forEach(System.out::println);
        log.info("找到符合条件的资产: {}");
        return "";
        // 你可以在这里对 asset 进行进一步处理

    }

    /**
     * 创建交易订单请求
     * @param orderAmount 订单金额
     * @param fromAccId 转账方账户id
     * @param cvuId 收款方账户id
     * @return
     * @throws IOException
     */
    public static String createTransferRequest(String orderAmount,String fromAccId,String cvuId) throws IOException {
        String url = String.format(CREATE_TRANSFER_URL,fromAccId, orderAmount,cvuId);
        Request request = new Request.Builder()
                .url(url)
                .get()
                .build();
        Response response = okHttpClient.newCall(request).execute();
        String responseString = response.body().string();
        log.info("创建交易订单："+responseString);
        return responseString;
    }

    public static String sendVerifyCodeRequest() throws IOException {
        String url = "https://dev.quikipay.com/account/resend-2faCode/cvu-withdrawal/send";
        Request request = new Request.Builder()
                .url(url)
                .get()
                .build();
        Response response = okHttpClient.newCall(request).execute();
        String responseString = response.body().string();
        log.info("发送验证码："+responseString);
        return responseString;
    }

    private static String sendTransferRequest(String token,String fromCvuId,String reference,String orderAmount,String verifyCode,String showSlider) throws IOException {
        //6.https://dev.quikipay.com/withdraw/store/cvu 输入验证码
        // 参数：_token=g9yKX5WhBcD9kFB6QvqG0b1ME9CjYWKeCvNCMqj2&cvu=224683&reference=100&amount=1.00&assets=418973&concept=VAR&twofa_mailed_code=123456&twofa_google_code=&show_slider=0
        // 参数：_token=GZ6KMTFc7U7Qe8mnQd8yI7cX5p1N7VSgpKOOJegH&cvu=224685&reference=100&amount=1.00&assets=407338&concept=VAR&twofa_mailed_code=&twofa_google_code=&show_slider=1
        String url = "https://dev.quikipay.com/withdraw/store/cvu";
        FormBody formBody = new FormBody.Builder()
                .add("_token", token)
                .add("cvu", fromCvuId)
                .add("reference", reference)
                .add("amount", orderAmount)
                .add("concept", "VAR")
                .add("twofa_mailed_code", verifyCode)
                .add("twofa_google_code", "")
                .add("show_slider", showSlider)
                .build();
        Request request = new Request.Builder()
                .url(url)
                .post(formBody)
                .build();
        Response response = okHttpClient.newCall(request).execute();
        String responseString = response.body().string();
        log.info("开始交易："+responseString);
        return responseString;
    }

    public static String getCsrfToken() throws IOException {
        String getCsrfTokenUrl = "https://dev.quikipay.com/system/get/csrf-token";
        Request request = new Request.Builder()
                .url(getCsrfTokenUrl)
                .get()
                .build();
        Response response = okHttpClient.newCall(request).execute();
        return response.body().string();
    }
}
